home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / jmodm308.arc / JMODEM_D.C < prev    next >
Text File  |  1991-01-02  |  8KB  |  135 lines

  1. /****************************************************************************/
  2. /*   FILE JMODEM_D.C                                                        */
  3. /*   Created 11-JAN-1990                  Richard B. Johnson                */
  4. /*                                        405 Broughton Drive               */
  5. /*                                        Beverly, Massachusetts 01915      */
  6. /*                                        BBS (508) 922-3166                */
  7. /*                                                                          */
  8. /*   encode();      (Data compression routine  )                            */
  9. /*   decode();      (Data expansion routine    )                            */
  10. /*   calc_crc();    (CRC checking and setting  )                            */
  11. /*                                                                          */
  12. /****************************************************************************/
  13. #include <stdlib.h>                             /* For _rotl()              */
  14. #include "jmodem.h"                             /* JMODEM primatives        */
  15. /****************************************************************************/
  16. /*                   Encode (compress) the input string.                    */
  17. /*   The routine looks for groups of identical characters and replaces them */
  18. /*   with the character  0xBB, a word denoting the number of characters to  */
  19. /*   duplicate, followed by the character to duplicate.                     */
  20. /*                                                                          */
  21. /****************************************************************************/
  22.  
  23. word encode(word len,                           /* Length of input string   */
  24.        register byte *in_buffer,                /* Pointer to input buffer  */
  25.        register byte *out_buffer)               /* Pointer to output buffer */
  26. {
  27.     word *wrds;                                 /* Used to address string   */
  28.     word how_many=0;                            /* Character count          */
  29.     word count=0;                               /* Output byte count        */
  30.     word start;                                 /* Starting count           */
  31.     byte dupl;                                  /* Character to replace     */
  32.  
  33.     start = len;                                /* Save starting length     */
  34.     while (len)                                 /* While bytes in buffer    */
  35.     {
  36.         if ( (*in_buffer == 0xBB)               /* If the sentinel byte     */
  37.           || (*in_buffer == *(in_buffer+1)) )   /* If two adjacent the same */
  38.         {
  39.             *out_buffer++ = 0xBB;               /* Insert , bump pointer    */
  40.             dupl = *in_buffer;                  /* Save duplicate character */
  41.             how_many = 0;                       /* Duplicate char count     */
  42.             while ( (*in_buffer++ == dupl)      /* Count duplicates         */
  43.                               && (len) )        /* While bytes still left.  */
  44.             {
  45.                 how_many++;                     /* Identical characters     */
  46.                 len --;                         /* Don't move to (while)    */
  47.             }
  48.             wrds = (word *)out_buffer;          /* Address string pointer   */
  49.             *wrds = how_many;                   /* Insert character count   */
  50.             out_buffer++;                       /* Adjust pointer           */
  51.             out_buffer++;                       /* (get past count)         */
  52.             *out_buffer++ = dupl;               /* The duplicate character  */
  53.             count += 4;                         /* Adjust byte count        */
  54.             in_buffer--;                        /* Non-duplicate character  */
  55.         }
  56.         else
  57.         {
  58.             *out_buffer++ = *in_buffer++;      /* Copy byte                 */
  59.             count++;                           /* Character count           */
  60.             len--;
  61.         }
  62.         if ( count > start )                   /* Check unwarranted growth  */
  63.             return JM_MAX;
  64.     }
  65.     return count;                              /* New length                */
  66. }
  67. /****************************************************************************/
  68. /*                     Decode (expand) the encoded string.                  */
  69. /*    Routine checks for a sentinel byte, 0xBB, and if found, takes the     */
  70. /*    following word as the number of identical bytes to add. The actual    */
  71. /*    byte to add is located following the length-word.                     */
  72. /*                                                                          */
  73. /****************************************************************************/
  74. word decode(word len,                           /* Length to input string   */
  75.        register byte *in_buffer,                /* Pointer to input buffer  */
  76.        register byte *out_buffer)               /* Pointer to output buffer */
  77. {
  78.     byte *start;                                /* To save buffer start     */
  79.     word *wrds;                                 /* Address string as word   */
  80.  
  81.     if (len > DAT_MAX)                          /* Check for valid data     */
  82.         return 0;
  83.     start = out_buffer;                         /* Save starting address    */
  84.     while (len--)
  85.     {
  86.         if (*in_buffer == 0xBB )                /* If the sentinel byte     */
  87.         {
  88.             wrds =(word *) ++in_buffer;         /* Next character           */
  89.             in_buffer++;                        /* Adjust buffer pointer    */
  90.             in_buffer++;                        /* (get past the count)     */
  91.             do                                  /* Expand the byte          */
  92.             {
  93.                 *out_buffer++ = *in_buffer;     /* Expand byte              */
  94.             }   while (--(*wrds) );
  95.             in_buffer++;                        /* Adjust pointer           */
  96.             len -=3;                            /* Adjust input count       */
  97.         }
  98.         else                                    /* Else, just copy          */
  99.             *out_buffer++ = *in_buffer++;
  100.     }
  101.     return (word) (out_buffer - start);         /* New string length        */
  102. }
  103. /****************************************************************************/
  104. /*                  Calculate the simple JMODEM CRC                         */
  105. /*    Routine obtains a pointer to the buffer of characters to be checked.  */
  106. /*    The first passed parameter is the length of the buffer. The CRC is    */
  107. /*    returned.                                                             */
  108. /*                                                                          */
  109. /****************************************************************************/
  110. word calc_crc(word command,                       /* Set or Check CRC       */
  111.               word length,                        /* Buffer length          */
  112.               register byte *buffer)              /* Pointer to the buffer  */
  113. {
  114.     register word *wrds;                          /* Address string as word */
  115.     word crc=0;                                   /* Start at zero          */
  116.  
  117.     if (length <3)                                /* Check forvalid string  */
  118.         return JM_MAX;                            /* Nothing to CRC         */
  119.  
  120.     length -=2;                                   /* Don't CRC the CRC      */
  121.     do
  122.     {
  123.     crc += (word) *buffer++;                      /* Sum first              */
  124.     crc  = _rotl(crc, (length & 0x07) );          /* Rotate max 7 bits left */
  125.     } while (--length);
  126.     wrds = (word *) buffer;                       /* Set up to point to CRC */
  127.     if (command == GET_CRC)
  128.         return (crc - *wrds);                     /* Return  0 if CRC okay  */
  129.     else                                          /* Else command = SET_CRC */
  130.         *wrds = crc;                              /* Set the CRC in  string */
  131.         return crc;                               /* Return the CRC also    */
  132. }
  133. /****************************************************************************/
  134. /************************ E N D  O F   M O D U L E **************************/
  135.